package com.youlu.campus.admin.course.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.admin.course.convert.CourseConvert;
import com.youlu.campus.admin.course.dto.CourseOrderRefundApplyDTO;
import com.youlu.campus.admin.course.dto.CourseOrderRefundOpDTO;
import com.youlu.campus.admin.course.dto.UserCourseOrderSearchDTO;
import com.youlu.campus.admin.course.service.CourseOrderService;
import com.youlu.campus.admin.course.vo.UserCourseOrderDetailVo;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.WechatMiniUserPO;
import com.youlu.campus.entity.course.CourseOrderRefundApply;
import com.youlu.campus.entity.course.UserCourseOrder;
import com.youlu.campus.entity.enums.CourseOrderStatusEnum;
import com.youlu.campus.entity.order.SharingProfitOrderDetail;
import com.youlu.campus.entity.system.UserDataPermission;
import com.youlu.campus.service.course.QueryWrapper;
import com.youlu.campus.service.course.UserCourseOrderService;
import com.youlu.campus.service.order.MerchantSharingProfitService;
import com.youlu.campus.service.system.UserDataPermissionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author : [dengbo]
 * @className : CourseOrderServiceImpl
 * @description : [描述说明该类的功能]
 * @createTime : [2022/5/20 22:32]
 */
@Service
@Slf4j
public class CourseOrderServiceImpl implements CourseOrderService {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private CourseConvert courseConvert;

    @Autowired
    private UserCourseOrderService userCourseOrderService;

    @Autowired
    private MerchantSharingProfitService merchantSharingProfitService;

    @Autowired
    private UserDataPermissionService userDataPermissionService;

    private final static String MOBILE_REGEX = "(\\d{3})\\d{4}(\\d{4})";

    @Override
    public Page<UserCourseOrderDetailVo> list(UserCourseOrderSearchDTO dto) {
        QueryWrapper query = new QueryWrapper();
        if (StringUtils.isNotBlank(dto.getOrderNo())) {
            query.where("orderNo", dto.getOrderNo());
        }
        if (StringUtils.isNotBlank(dto.getPhone())) {
            query.where("phone", dto.getPhone());
        }
//        if (StringUtils.isNotBlank(dto.getActivityName())) {
//            List<ActivityInfo> list = queryActivityInfo(dto.getActivityName());
//            if (CollectionUtils.isNotEmpty(list)) {
//                List<String> activityIdList = list.stream().map(ActivityInfo::getId).collect(Collectors.toList());
//                // 查询活动
//                query.in("activityId", activityIdList);
//            }
//        }
        if (StringUtils.isNotBlank(dto.getCourseId())) {
            query.where("courseId", dto.getCourseId());
        }
        if (dto.getStatus() != null) {
            query.where("status", dto.getStatus());
        }
        PageRequest pageRequest = PageRequest.of(dto.getPage() - 1, dto.getPageSize());
        UserDataPermission req = new UserDataPermission();
        req.setUserId(dto.getUserId());
        List<UserDataPermission> userDataPermissionList = userDataPermissionService.list(req);
        if (CollectionUtils.isEmpty(userDataPermissionList) || CollectionUtils.isEmpty(userDataPermissionList.get(0).getActivityId())) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0L);
        }
        Set<String> activityIdSet = userDataPermissionList.get(0).getActivityId().stream().collect(Collectors.toSet());
        String activityId = dto.getActivityId();
        if (StringUtils.isNotBlank(activityId)) {
            //如果活动存在分配权限中则查询
            if (activityIdSet.contains(activityId)) {
                query.addCriteria(Criteria.where("activityId").is(activityId));
            } else {
                return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0L);
            }
        } else {
            query.addCriteria(Criteria.where("activityId").in(activityIdSet));
        }
        long count = mongoTemplate.count(query, UserCourseOrder.class);

        query.with(Sort.by(Sort.Order.desc("id")));
        List<UserCourseOrder> result = mongoTemplate.find(query.with(pageRequest), UserCourseOrder.class);
        if(CollectionUtils.isNotEmpty(result)){
            result.stream().forEach(userCourseOrder -> {
                    SharingProfitOrderDetail sharingProfitOrderDetail  = merchantSharingProfitService.getSharingProfitAmountByOrderNo(userCourseOrder.getOrderNo());
                    if(Objects.nonNull(sharingProfitOrderDetail)){
                        userCourseOrder.setSharingProfitStatus(sharingProfitOrderDetail.getSharingProfitStatus());
                        Integer  sharingProfitAmount = sharingProfitOrderDetail.getSharingProfitAmount();
                        userCourseOrder.setSharingProfitAmount(sharingProfitAmount);
                    }else{
                        userCourseOrder.setSharingProfitStatus(5);
                    }
            });
        }
        List<String> activityList = result.stream().map(UserCourseOrder::getActivityId).distinct().collect(Collectors.toList());
        List<String> userIdList = result.stream().map(UserCourseOrder::getUserId).distinct().collect(Collectors.toList());
        QueryWrapper activityQuery = new QueryWrapper();
        activityQuery.select("name", "id").in("id", activityList);
        List<ActivityInfo> datas = mongoTemplate.find(activityQuery, ActivityInfo.class);
        Map<String, String> map = datas.stream().collect(Collectors.toMap(ActivityInfo::getId, ActivityInfo::getName, (o1, o2) -> o2));
        // 查询unionID
        Query query1 = new Query(Criteria.where("accountInfoId").in(userIdList));
        List<WechatMiniUserPO> poList = mongoTemplate.find(query1, WechatMiniUserPO.class);
        Map<String, WechatMiniUserPO> userMap = poList.stream().collect(Collectors.toMap(WechatMiniUserPO::getAccountInfoId, Function.identity(), (o1, o2) -> o2));
        List<UserCourseOrderDetailVo> list = courseConvert.orderToDetailVoList(result, map, userMap);
        list.stream().forEach(userCourseOrder->{
            if(StringUtils.isNotBlank(userCourseOrder.getPhone())){
                if (dto.getMobileHide()) {//手机号是否要隐藏
                    userCourseOrder.setPhone("");
                } else {
                    if (dto.getMobileDesensitization()) {//手机号是否要脱敏
                        userCourseOrder.setPhone(userCourseOrder.getPhone().replaceAll(MOBILE_REGEX, "$1****$2"));
                    }
                }
            }
        });

        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    @Override
    public boolean refundApply(CourseOrderRefundApplyDTO apply) {
        log.info(":>>> 开始处理退款申请:{}",JSON.toJSON(apply));
        //校验订单
        Query orderQuery = Query.query(Criteria.where("id").is(apply.getOrderId()));
        UserCourseOrder order = mongoTemplate.findOne(orderQuery, UserCourseOrder.class);
        if (order == null) {
            throw new BusinessException("订单信息不存在");
        }
        if (order.getStatus().equals(CourseOrderStatusEnum.REFUND_COMPLETE.getValue())) {
            throw new BusinessException("订单已经退款");
        }
        if (order.getStatus().equals(CourseOrderStatusEnum.REFUND_APPLY.getValue())) {
            throw new BusinessException("订单退款申请中");
        }
        if (!order.getStatus().equals(CourseOrderStatusEnum.PAY_SUCCESS.getValue())) {
            throw new BusinessException("订单不是支付状态不能申请退款");
        }
        CourseOrderRefundApply refundApply = mongoTemplate.findOne(Query.query(Criteria.where("orderId").is(apply.getOrderId())
                .and("status").is(0)), CourseOrderRefundApply.class);
        if (refundApply != null) {
            throw new BusinessException("已经存在申请中的退款");
        }
        // 处理退款操作
        orderQuery.addCriteria(Criteria.where("status").is(CourseOrderStatusEnum.PAY_SUCCESS.getValue()));
        Update update = Update.update("status", CourseOrderStatusEnum.REFUND_APPLY.getValue());
        UpdateResult result = mongoTemplate.updateFirst(orderQuery, update, UserCourseOrder.class);
        log.info("CourseOrderService,refundApply,orderId:{} update order result:{}", apply.getOrderId(), JSONObject.toJSONString(result));
        if (result.getModifiedCount() <= 0) {
            throw new BusinessException("退款申请失败");
        }
        // 申请成功
        refundApply = new CourseOrderRefundApply();
        refundApply.setApplyReason(apply.getReason());
        refundApply.setOrderId(order.getId());
        refundApply.setOrderNo(order.getOrderNo());
        refundApply.setApplyTime(LocalDateTime.now());
        refundApply.setStatus(0);
        mongoTemplate.insert(refundApply);
        return true;
    }

    @Override
    public boolean refundOp(CourseOrderRefundOpDTO opDTO) {
        log.info(":>>> 开始审核退款申请:{}",JSON.toJSON(opDTO));
        // 校验订单
        Query orderQuery = Query.query(Criteria.where("id").is(opDTO.getOrderId()));
        UserCourseOrder order = mongoTemplate.findOne(orderQuery, UserCourseOrder.class);
        if (order == null) {
            throw new BusinessException("订单信息不存在");
        }
        if (order.getPrice() <= 0) {
            throw new BusinessException("0元不能退款");
        }
        if (!order.getStatus().equals(CourseOrderStatusEnum.REFUND_APPLY.getValue())) {
            throw new BusinessException("不是退款申请状态,不能操作");
        }
        // 处理退款操作
        Query query = Query.query(Criteria.where("orderId").is(opDTO.getOrderId()).and("status").is(0));
        CourseOrderRefundApply refundApply = mongoTemplate.findOne(query, CourseOrderRefundApply.class);
        if (refundApply == null) {
            throw new BusinessException("没有退款申请");
        }
        // 是否退款
        boolean refund = opDTO.getType().equals(1);
        Update update = refund ? Update.update("status", 2) : Update.update("status", 1);
        if (StringUtils.isNotBlank(opDTO.getReason())) {
            update.set("opReason", opDTO.getReason());
        }
        update.set("opTime", LocalDateTime.now());
        UpdateResult result = mongoTemplate.updateFirst(query, update, CourseOrderRefundApply.class);
        log.info("CourseOrderService,refundOp,orderNo:{} update result:{}", refundApply.getOrderNo(), JSONObject.toJSONString(result));
        if (refund && result.getModifiedCount() > 0) {
            userCourseOrderService.passRefundApply(order, refundApply.getId());
            return true;
        }
        // 驳回更新订单状态
        userCourseOrderService.rejectedRefundApply(refundApply.getOrderNo());
        return true;
    }

    public List<ActivityInfo> queryActivityInfo(String activityName) {
        QueryWrapper query = new QueryWrapper();
        query.select("id", "name");
        query.like("name", activityName);
        return mongoTemplate.find(query, ActivityInfo.class);
    }
}
